package cn.edu.tju.ldj.analytics.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.edu.tju.ldj.analytics.Const;
import cn.edu.tju.ldj.analytics.Factory;
import cn.edu.tju.ldj.analytics.alphas.IAlphaEngine;
import cn.edu.tju.ldj.analytics.vo.Broker;
import cn.edu.tju.ldj.analytics.vo.Contract;
import cn.edu.tju.ldj.analytics.vo.Good;
import cn.edu.tju.ldj.analytics.vo.GoodType;

public class DataProcessor {
	public List<Broker> loadSrcData(){
		List<Broker> brokerLst = new ArrayList<Broker>();
		List<GoodType> goodTypeLst = Factory.utilParam.getGoodTypeLst();
		for (int i = 0; goodTypeLst != null && i < goodTypeLst.size(); i++) {
			String goodType = goodTypeLst.get(i).getGoodTypeId();
			List<String> goodBrokerPathLst = getSubFiles(
					Factory.utilParam.getWebappsPath()
							+ goodTypeLst.get(i).getGoodTypeDir(), true);
			for (int j = 0; j < goodBrokerPathLst.size(); j++) {
				String brokerId = goodBrokerPathLst.get(j).substring(goodBrokerPathLst.get(j).lastIndexOf("/")+1, goodBrokerPathLst.get(j).length());
				String brokerName = Factory.utilParam.getDictionary(brokerId);
				List<Good> goodLst = new ArrayList<Good>();
				List<String> goodPathLst = getSubFiles(goodBrokerPathLst.get(j),
						false);
				for (int k = 0; k < goodPathLst.size(); k++) {
					if(goodPathLst.get(k).endsWith("csv")){
						String rex = "/";
						if(!goodPathLst.get(k).contains("/")){
							rex = "\\";
						}
						String goodId = goodPathLst.get(k).substring(goodPathLst.get(k).lastIndexOf(rex)+1, goodPathLst.get(k).lastIndexOf("csv")-1);
						String goodName = Factory.utilParam.getDictionary(goodId);
						String goodSrcUrl = goodPathLst.get(k);
						String goodTargetUrl = Factory.utilParam.getParam(Const.PARAM_FILE_SECTION_SVLT_GOODURL, goodId);
						Good newGood = new Good();
						newGood.setId(goodId);
						newGood.setGoodName(goodName);
						newGood.setGoodSrcUrl(goodSrcUrl);
						newGood.setGoodTargetUrl(goodTargetUrl);
						goodLst.add(newGood);
					}
				}
				Broker newBroker = new Broker();
				newBroker.setBrokerId(brokerId);
				newBroker.setBrokerName(brokerName);
				newBroker.setBrokerGoodLst(goodLst);
				newBroker.setGoodType(goodType);
				brokerLst.add(newBroker);
			}
		}
		
		return brokerLst;
	}
	
	private static List<String> getSubFiles(String filePath, boolean isDir) {
		List<String> fileLst = new ArrayList<String>();
		File root = new File(filePath);
		File[] files = root.listFiles();
		if(files != null){
			for (File file : files) {
				if (file.isDirectory()) {
					if(isDir){
						fileLst.add(file.getAbsolutePath());
					}
				} else {
					if(!isDir){
						fileLst.add(file.getAbsolutePath());
					}
				}
			}
		}
		else{
			System.out.println("找不到指定的文件");
		}
		
		return fileLst;
	}
	
	public void loadContractsForGood(Good temGood) throws Exception {
		// TODO Auto-generated method stub
		if(temGood.getGoodContractLst().size() == 0){
			try {
				String encoding = "GBK";
				File file = new File(temGood.getGoodSrcUrl());
				if (file.isFile() && file.exists()) { // 判断文件是否存在
					InputStreamReader read = new InputStreamReader(
							new FileInputStream(file), encoding);// 考虑到编码格式
					BufferedReader bufferedReader = new BufferedReader(read);
					String lineTxt = null;
					int num =0;
					Map<String,Contract> temContractMap = temGood.getGoodContracts();
					Contract curContract = null;
					Date dt;
					SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
					Map<String, Map<String,Object>> crtcDataTemp = new HashMap<String, Map<String,Object>>();
					while ((lineTxt = bufferedReader.readLine()) != null){// && ) {
						if(num>30){
							break;
						}
						if(lineTxt.length() == 0){
							continue;
						}
						if(lineTxt.contains("#")){
							String ctrctId = lineTxt.replaceAll("#", "");
							if(!temContractMap.containsKey(ctrctId)){
								curContract = new Contract();
								curContract.setCtrctId(ctrctId);
								curContract.setCtrctName(temGood.getGoodName() + ctrctId);
								curContract.setCtrctUrl(Factory.utilParam.getParam(Const.PARAM_FILE_SECTION_SVLT_CTRCTURL, ctrctId));
								temContractMap.put(ctrctId, curContract);
							}
							else{
								curContract = temContractMap.get(ctrctId);
							}
							continue;
						}
						String [] dataStr = lineTxt.split(",");
						if(dataStr.length >= 5 ){
							Map<String,Object> newDayData = new HashMap<String, Object>();
							for (int j = 0; j < dataStr.length; j++) {
								dataStr[j] = dataStr[j].replaceAll(",", "").replaceAll("\\.00", "").replaceAll("\"", "").replaceAll("	", "");
							}
							
							try{
								dt = sdf.parse((String) dataStr[0]);
								newDayData.put("date", dt.getTime());
								newDayData.put("open", Double.parseDouble(dataStr[1]));
								newDayData.put("high", Double.parseDouble(dataStr[2]));
								newDayData.put("low", Double.parseDouble(dataStr[3]));
								newDayData.put("close", Double.parseDouble(dataStr[4]));
								newDayData.put("volume", Integer.parseInt(dataStr.length==5?"0":dataStr[5]));
								curContract.getCtrctDayDataLst().add(newDayData);
								if(crtcDataTemp.containsKey(""+(Long)newDayData.get("date"))){
									if( (Integer)crtcDataTemp.get(""+(Long)newDayData.get("date")).get("volume") < (Integer)newDayData.get("volume")){
										crtcDataTemp.remove(""+(Long)newDayData.get("date"));  //去掉重复的数据
										crtcDataTemp.put(""+(Long)newDayData.get("date"), newDayData);
									}
								}else{
									crtcDataTemp.put(""+(Long)newDayData.get("date"), newDayData);
								}
							}catch (Exception e) {
								// TODO: handle exception
								e.printStackTrace();
							}
						}
						else{
							System.out.println(lineTxt);
						}
//						num++;
					}
					num = 0;
					for (int i = 0; i < curContract.getCtrctId().length(); i++) {
						if(Character.isDigit(curContract.getCtrctId().charAt(i))){
							num = i;
							break;
						}
					}
					
					Contract indexCtct = new Contract();
					indexCtct.setCtrctId(curContract.getCtrctId().substring(0, num) + 9999999);
					indexCtct.setCtrctName(curContract.getCtrctName().substring(0, curContract.getCtrctName().lastIndexOf("）") +1) + "Index");
					indexCtct.setCtrctUrl(Factory.utilParam.getParam(Const.PARAM_FILE_SECTION_SVLT_CTRCTURL, indexCtct.getCtrctId()));
					
					for (String key:crtcDataTemp.keySet()) {
						indexCtct.getCtrctDayDataLst().add(crtcDataTemp.get(key));
					}
					
					Map<String,Object> temDayData = new HashMap<String, Object>();
					for (int i = 0; i < indexCtct.getCtrctDayDataLst().size(); i++) {
						for (int j = 1; j < indexCtct.getCtrctDayDataLst().size()-i; j++) {
							if((Long)indexCtct.getCtrctDayDataLst().get(j-1).get("date") > (Long)indexCtct.getCtrctDayDataLst().get(j).get("date")){
								temDayData = indexCtct.getCtrctDayDataLst().get(j-1);
								indexCtct.getCtrctDayDataLst().set(j-1, indexCtct.getCtrctDayDataLst().get(j));
								indexCtct.getCtrctDayDataLst().set(j, temDayData);
							}
						}
					}
					
					temContractMap.put(indexCtct.getCtrctId(), indexCtct);
					read.close();
				} else {
					System.out.println("找不到指定的文件");
				}
			} catch (Exception e) {
				System.out.println("读取文件内容出错");
				e.printStackTrace();
			}
		}
		
		for (int i = 0; i < temGood.getGoodContractLst().size(); i++) {
			getSimulationResults(temGood.getGoodContractLst().get(i));
		}
	}

	@SuppressWarnings("static-access")
	public String initContractInfoJson(Contract ct) {
		// TODO Auto-generated method stub
		String resultJsonStr = "{\"data\":\n[";
		DecimalFormat df = new DecimalFormat("#.00");
		
		for (int i = 0; i < ct.getCtrctDayDataLst().size(); i++) {
			resultJsonStr += 
					"\n[" + ct.getCtrctDayDataLst().get(i).get("date")
					+ "," + ct.getCtrctDayDataLst().get(i).get("open")
					+ "," + ct.getCtrctDayDataLst().get(i).get("high")
					+ "," + ct.getCtrctDayDataLst().get(i).get("low")
					+ "," + ct.getCtrctDayDataLst().get(i).get("close")
					+ "," + ct.getCtrctDayDataLst().get(i).get("volume")
					+ "," + df.format((Double)ct.getCtrctDayDataLst().get(i).get("avg1"))
					+ "," + df.format((Double)ct.getCtrctDayDataLst().get(i).get("avg2"))
					+ "," + df.format((Double)ct.getCtrctDayDataLst().get(i).get("avg3"))
					+ "," + df.format((Double)ct.getCtrctDayDataLst().get(i).get("avg4"))
					+ "],";
		}
		resultJsonStr = resultJsonStr.substring(0, resultJsonStr.length()-1);
		resultJsonStr += "]}";
//		System.out.println(resultJsonStr);
		Factory.utilFile.writeFile(Factory.utilParam.getWebappsPath()
				+ Factory.utilParam.getParam(Const.PARAM_FILE_SECTION_TARGET_PATH) + "candlestick-and-volume.json", resultJsonStr);
		return ct.getCtrctName();
	}
	
	public void getAvgs(Contract ct){
		Double avg1, avg2, avg3, avg4;
		
		for (int i = 0; i < ct.getCtrctDayDataLst().size(); i++) {
			avg1 = (Double)ct.getCtrctDayDataLst().get(i).get("close");
			if(i < 6){
				avg2 = avg1;
				avg3 = avg1;
				avg4 = avg1;
			}else if(i < 11){
				avg1 = 0.0;
				for (int j = 0; j < 5; j++) {
					avg1 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg1 = avg1/5;
				avg2 = avg1;
				avg3 = avg1;
				avg4 = avg1;
			}else if(i < 21){
				avg1 = 0.0;
				avg2 = 0.0;
				for (int j = 0; j < 5; j++) {
					avg1 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg1 = avg1/5;
				
				for (int j = 0; j < 10; j++) {
					avg2 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg2 = avg2/10;
				avg3 = avg2;
				avg4 = avg2;
			}else if(i < 36){
				avg1 = 0.0;
				avg2 = 0.0;
				avg3 = 0.0;
				for (int j = 0; j < 5; j++) {
					avg1 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg1 = avg1/5;
				
				for (int j = 0; j < 10; j++) {
					avg2 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg2 = avg2/10;
				
				for (int j = 0; j < 20; j++) {
					avg3 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg3 = avg3/20;
				avg4 = avg3;
			}else{
				avg1 = 0.0;
				avg2 = 0.0;
				avg3 = 0.0;
				avg4 = 0.0;
				for (int j = 0; j < 5; j++) {
					avg1 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg1 = avg1/5;
				
				for (int j = 0; j < 10; j++) {
					avg2 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg2 = avg2/10;
				
				for (int j = 0; j < 20; j++) {
					avg3 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg3 = avg3/20;
				
				for (int j = 0; j < 35; j++) {
					avg4 += (Double)ct.getCtrctDayDataLst().get(i-j).get("close");
				}
				avg4 = avg4/35;
			}
			ct.getCtrctDayDataLst().get(i).put("avg1", avg1);
			ct.getCtrctDayDataLst().get(i).put("avg2", avg2);
			ct.getCtrctDayDataLst().get(i).put("avg3", avg3);
			ct.getCtrctDayDataLst().get(i).put("avg4", avg4);
		}
	}
	
	private void getSimulationResults(Contract contract) throws Exception {
		// TODO Auto-generated method stub
		IAlphaEngine alpahEngine = Factory.servGood.getAlphaEngine(Factory.utilParam.getCurAlpha());
		if(contract.getCtrctDayDataLst().size() > 0){
			if(!contract.getCtrctDayDataLst().get(0).containsKey("agv1")){
				getAvgs(contract);
			}
		}
		alpahEngine.processSimulation(contract, false);
	}
}
